-- sprites
local prefix = 'resources.sprites.atlasses.'
local prefixS = 'resources/sprites/atlasses/'

-- 0
local sprite0Info = require (prefix .. 'c0-hd')
local sprite0 = graphics.newImageSheet( prefixS .. 'c0-hd.png', sprite0Info:getSheet() )
-- 45
local sprite45Info = require (prefix .. 'c45-hd')
local sprite45 = graphics.newImageSheet( prefixS .. 'c45-hd.png', sprite45Info:getSheet() )
-- 90
local sprite90Info = require (prefix .. 'c90-hd')
local sprite90 = graphics.newImageSheet( prefixS .. 'c90-hd.png', sprite90Info:getSheet() )
-- 135
local sprite135Info = require (prefix .. 'c135-hd')
local sprite135 = graphics.newImageSheet( prefixS .. 'c135-hd.png', sprite135Info:getSheet() )
-- 180
local sprite180Info = require (prefix .. 'c180-hd')
local sprite180 = graphics.newImageSheet( prefixS .. 'c180-hd.png', sprite180Info:getSheet() )
-- 225
local sprite225Info = require (prefix .. 'c225-hd')
local sprite225 = graphics.newImageSheet( prefixS .. 'c225-hd.png', sprite225Info:getSheet() )
-- 270
local sprite270Info = require (prefix .. 'c270-hd')
local sprite270 = graphics.newImageSheet( prefixS .. 'c270-hd.png', sprite270Info:getSheet() )
-- 315
local sprite315Info = require (prefix .. 'c315-hd')
local sprite315 = graphics.newImageSheet( prefixS .. 'c315-hd.png', sprite315Info:getSheet() )

local time = 1000
local sequence = {{
   name = 'r', sheet = sprite0, start = 1, count = 5, time = time, loopCount = 0
}, {
   name = 'tr', sheet = sprite45, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 't', sheet = sprite90, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 'tl', sheet = sprite135, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 'l', sheet = sprite180, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 'bl', sheet = sprite225, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 'b', sheet = sprite270, start = 1, count = 5, time = time, loopCount = 0   
}, {
   name = 'br', sheet = sprite315, start = 1, count = 5, time = time, loopCount = 0   
}}

local Player = {}

function Player:new( x, y, grid )
   local player = display.newGroup()
   player.sprite = display.newSprite( player, sprite0, sequence )
   player.sprite:scale(0.1, 0.1)

   -- gravity debug
   local function transformGravity( gx, gy )
      gx = gx or 0
      gy = gy or 0
      return {
         x = -gy,
         y = -gx
      }
   end

   player.actualLife = 100
   player.lifeText = display.newText({
      parent = player,
      y = -Y*0.05,
      text = '100/100',
      fontSize = 8
   })
   player.lifeRectangle = display.newRect(player, 0, -Y*0.1, X*0.1, Y*0.02)
   player.lifeRectangle.strokeWidth = 1
   player.lifeRectangle:setStrokeColor( 1, 1, 1 )
   player.lifeRectangle:setFillColor( 0, 1, 0, 1 )

   function player:updateLifeView()
      player.lifeText.text = string.format("%d", player.actualLife) .. '/100'
      local colorLife = player.actualLife / 100.0
      player.lifeRectangle:setFillColor( 1.0-colorLife, colorLife, 0, 1 )
   end

   function player:lifeUpdate(delta)
      local lifeUpdated = player.actualLife + delta
      if lifeUpdated < 0 then
         lifeUpdated = 0
      end
      if lifeUpdated > 100 then
         lifeUpdated = 100
      end
      player.actualLife = lifeUpdated
      player:updateLifeView()
   end

   function player:setFullLife()
      
   end

   function player:init( x, y, grid )
      self.x = x
      self.y = y

      Runtime:addEventListener( 'accelerometer', function( event )
         self.gx = event.xGravity
         self.gy = event.yGravity
      end )

      Runtime:addEventListener( 'touch', player )
   end

   function player:update( delta )
      -- update position
      local border = 10
      self:moveByAccelerometer( delta )
      -- self:moveByTap( delta )
      self.x = math.min(math.max(self.x, border), X - border)
      self.y = math.min(math.max(self.y, border), Y - border)

      -- update life
      local cell = grid:getCellFromCoordinates(self.x, self.y)
      cell:modifyPlayerState(self, delta)
   end

   function player:touch(event)
      if event.phase == "began" then
         local x = event.x
         local y = event.y
         local mult = 10
         if x < y then
            if x+y > Y then -- DOWN
               self.tox, self.toy = 0, 1
            else -- LEFT
               self.tox, self.toy = -1, 0
            end
         else
            if x+y > Y then -- RIGHT
               self.tox, self.toy = 1, 0
            else -- UP
               self.tox, self.toy = 0, -1
            end
         end
      else
         self.tox = 0
         self.toy = 0
      end

      player:lifeUpdate(-1)
   end

   function player:moveByAccelerometer( delta )
      local g = transformGravity( self.gx, self.gy )
      local xMult = (g.x < 0 and -1) or 1
      local yMult = (g.y < 0 and -1) or 1
      -- player.debug.text = g.x .. '   ' .. g.y
      if math.abs(g.x) < 0.05 then g.x = 0 else g.x = xMult end
      if math.abs(g.y) < 0.05 then g.y = 0 else g.y = yMult end

      local mult = 100
      self:move( g.x * mult * delta, g.y * mult * delta )
   end

   function player:moveByTap( delta )
      local mult = 100.0
      if self.tox or self.toy then
         self:move( self.tox * delta * mult, self.toy * delta * mult )
      end
   end

   local oldS = 's'
   function player:move(dx, dy)
      local s = 's'

      -- print(dx, dy)
      if dx > 0  and dy == 0 then s = 'r' end
      if dx > 0  and dy < 0  then s = 'tr' end
      if dx == 0 and dy < 0  then s = 't' end
      if dx < 0  and dy < 0  then s = 'tl' end
      if dx < 0  and dy == 0 then s = 'l' end
      if dx < 0  and dy > 0  then s = 'bl' end
      if dx == 0 and dy > 0  then s = 'b' end
      if dx > 0  and dy > 0  then s = 'br' end
      
      if s ~= 's' then
         if oldS ~= s then
            print('change')
            self.sprite:setSequence( s )
            self.sprite:play()
         end
      else
         -- print('pause')            
         self.sprite:pause()
      end

      self.x = self.x + dx
      self.y = self.y + dy
      oldS = s
      assert(oldS ~= nil)
   end

   player:init(x, y, grid)

   return player
end

return Player